﻿using Common.Communication;
using Common.Db.SysDb;
using Common.Tool.DataTools;
using DeviceBase;
using DeviceBase.Configs;
using DeviceBase.Interfaces;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace DianYuan.Core.QingDu
{
    public class AC11005SerialPort : SerialPortBase, IDianYuan
    {
        public string Name { get; set; }
        byte Addr { get; set; }
        public AC11005SerialPort(string name, int addr, string portName, int baudRate = 115200, int timeout = 1000) : base(portName, baudRate, timeout: timeout)
        {
            Name = name;
            Addr = (byte)addr;
        }
        public Result<bool> SetOn(double vol, double cur = 0, int channel = 1)
        {
            Result<bool> result = new Result<bool>();
            AppendInfo(Name, $"通道{channel}设置输出{vol}V");
            var command = CmdSetVol(vol);
            var re = WriteThenRead(command);
            if (!re.IsSucceed || !re.Value.SequenceEqual(command))
            {
                result.IsSucceed = false;
                result.Err = "设置输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            Thread.Sleep(100);
            command = CmdGetSetVol();
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || !re2.Value.SequenceEqual(CmdGetSetVolOk(vol)))
            {
                result.IsSucceed = false;
                result.Err = "设置输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            AppendInfo(Name, $"通道{channel}打开输出");
            command = CmdOutPutOn();
            re = WriteThenRead(command);
            if (!re.IsSucceed || !re.Value.SequenceEqual(command))
            {
                result.IsSucceed = false;
                result.Err = "打开输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            Thread.Sleep(100);
            command = CmdGetOutPut();
            //发送指令并返回
            re2 = WriteThenRead(command);
            if (!re2.IsSucceed || !re2.Value.SequenceEqual(CmdOn()))
            {
                result.IsSucceed = false;
                result.Err = "打开输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            AppendInfo(Name, "设置输出成功");
            return result.EndTime();
        }
        public Result<bool> SetOff(int channel = 1)
        {
            Result<bool> result = new Result<bool>();
            AppendInfo(Name, $"通道{channel}关闭输出");
            var command = CmdOutPutOff();
            var re = WriteThenRead(command);
            if (!re.IsSucceed || !re.Value.SequenceEqual(command))
            {
                result.IsSucceed = false;
                result.Err = "关闭输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            Thread.Sleep(100);
            command = CmdGetOutPut();
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || !re2.Value.SequenceEqual(CmdOff()))
            {
                result.IsSucceed = false;
                result.Err = "关闭输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            AppendInfo(Name, "关闭输出成功");
            return result.EndTime();
        }
        public Result<double> GetVoltage(int channel = 1)
        {
            Result<double> result = new Result<double>();
            AppendInfo(Name, $"通道{channel}读取当前电压");
            var command = CmdGetVolt();
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || re2.Value.Length != 7 || !re2.Value.Take(3).SequenceEqual(new byte[] { Addr, 0x03, 0x02 }))
            {
                result.IsSucceed = false;
                result.Err = "读取当前电压失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            result.Value = ((re2.Value[3] << 8) + re2.Value[4]) / 10.0f;
            AppendResult(Name, DataConvert.ToUnit(result.Value, "F3") + "V");
            return result.EndTime();
        }
        public Result<double> GetCurrent(int channel = 1)
        {
            Result<double> result = new Result<double>();
            AppendInfo(Name, $"通道{channel}读取当前电流");
            var command = CmdGetCurr();
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || re2.Value.Length != 7 || !re2.Value.Take(3).SequenceEqual(new byte[] { Addr, 0x03, 0x02 }))
            {
                result.IsSucceed = false;
                result.Err = "读取当前电流失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            result.Value = ((re2.Value[3] << 8) + re2.Value[4]) / 10.0f;
            AppendResult(Name, DataConvert.ToUnit(result.Value, "F3") + "A");
            return result.EndTime();
        }

        byte[] CmdSetVol(double value)
        {
            int vol = Convert.ToInt32(value * 10);
            byte h = Convert.ToByte((vol >> 8) & 0xff);
            byte l = Convert.ToByte(vol & 0xff);
            byte[] data = new byte[] { Addr, 0x06, 0x00, 0x08, h, l };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdGetSetVol()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x08, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdGetSetVolOk(double value)
        {
            int vol = Convert.ToInt32(value * 10);
            byte h = Convert.ToByte((vol >> 8) & 0xff);
            byte l = Convert.ToByte(vol & 0xff);
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x01, h, l };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdOutPutOn()
        {
            byte[] data = new byte[] { Addr, 0x06, 0x00, 0x09, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdOutPutOff()
        {
            byte[] data = new byte[] { Addr, 0x06, 0x00, 0x09, 0x00, 0x00 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdGetOutPut()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x09, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdOn()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x02, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdOff()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x02, 0x00, 0x00 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdGetVolt()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x02, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
        byte[] CmdGetCurr()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x03, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, true);
        }
    }
}
